package cn.edu.soft.fastdfs;

import cn.edu.soft.fastdfs.client.StorageClient;
import cn.edu.soft.fastdfs.client.TrackerClient;
import cn.edu.soft.fastdfs.client.StorageClientFactory;
import cn.edu.soft.fastdfs.client.TrackerClientFactory;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;

import java.util.List;

public class FastdfsClientFactory implements FactoryBean<FastdfsClient> {

    private static volatile FastdfsClient fastdfsClient;

    private FastdfsClientConfig config;

    public FastdfsClientConfig getConfig() {
        return config;
    }

    public void setConfig(FastdfsClientConfig config) {
        this.config = config;
    }

    @Override
    public FastdfsClient getObject() throws Exception {
        int connectTimeout = config.getConnectTimeout();
        int networkTimeout = config.getNetworkTimeout();
        TrackerClientFactory trackerClientFactory = new TrackerClientFactory(connectTimeout, networkTimeout);
        StorageClientFactory storageClientFactory = new StorageClientFactory(connectTimeout, networkTimeout);
        GenericKeyedObjectPoolConfig trackerClientPoolConfig = config.getTrackerClientPoolConfig();
        GenericKeyedObjectPoolConfig storageClientPoolConfig = config.getStorageClientPoolConfig();
        GenericKeyedObjectPool<String, TrackerClient> trackerClientPool = new GenericKeyedObjectPool<>(trackerClientFactory, trackerClientPoolConfig);
        GenericKeyedObjectPool<String, StorageClient> storageClientPool = new GenericKeyedObjectPool<>(storageClientFactory, storageClientPoolConfig);
        List<String> trackerAddrs = config.getTrackerAddrs();
        return new FastdfsClientImpl(trackerAddrs, trackerClientPool, storageClientPool);
    }

    @Override
    public Class<?> getObjectType() {
        return FastdfsClient.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

}
